package com.ybear.ybcomponent.widget.linkage.effector

import android.animation.ObjectAnimator
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup.MarginLayoutParams
import android.view.animation.LinearInterpolator
import com.ybear.ybcomponent.widget.linkage.effector.base.CoreEffector
import com.ybear.ybcomponent.widget.linkage.enums.ViewLinkage
import kotlin.math.abs

/**
 * @Author MiWi
 * @Date 2025年2月13日
 * @Description Linkage - 缩放效果器
 */
open class ZoomEffector : CoreEffector() {
    open var currentScrollY = 0F
        protected set
    open var currentViewWidth = 0
        protected set
    open var currentViewHeight = 0
        protected set
    open var isScaling = false
        protected set

    open var scaleTimesMax = 2F
    open var scaleRatio = 0.8F
    open var replyRatio = 0.5F

    override fun onViewLinkage(): ViewLinkage = ViewLinkage.ZOOM

    override fun onEffector(startOffset: Float, endOffset: Float) : Boolean {
        if ( currentViewWidth <= 0 || currentViewHeight <= 0 ) {
            currentViewWidth = childView.measuredWidth
            currentViewHeight = childView.measuredHeight
        }
        when ( motionEvent.action ) {
            MotionEvent.ACTION_MOVE -> {
                // ACTION_MOVE：计算滑动距离并动态调整视图高度
                val evY = motionEvent.y
                // 如果滑动距离未达到生效范围或超过终点偏移，则不处理
                if ( endOffset != 0F && abs( evY.px2Dp ) > endOffset ) return false
                if ( !isScaling ) {
                    if ( parent.scrollY == 0 ) currentScrollY = abs( evY ) else return false
                }
                val distance = ( ( abs( evY ) - currentScrollY - startOffset ) * scaleRatio )
                    .coerceAtMost( endOffset ).toInt()
                if ( distance < 0 ) return false
                isScaling = true
                setZoom( distance.toFloat(), childView )
            }

            MotionEvent.ACTION_UP,
            MotionEvent.ACTION_CANCEL -> {
                if( isScaling ) {
                    isScaling = false
                    restoreView( childView )
                }
            }
        }
        return false
    }

    override fun restoreEffector(animator: Boolean) {
        if( animator ) {
            restoreView( childView )
            return
        }
        setZoom( 0F, childView )
    }

    /**
     * 设置缩放
     */
    private fun setZoom(s: Float, view: View) {
        val scaleTimes = ( currentViewWidth + s ) / currentViewWidth.toFloat()
        if ( scaleTimes > scaleTimesMax ) return
        view.layoutParams = ( view.layoutParams as MarginLayoutParams).apply {
            width = ( currentViewWidth + s ).toInt()
            height = ( currentViewHeight * scaleTimes ).toInt()
            setMargins( -( width - currentViewWidth ) / 2, 0, 0, 0 )
        }
        view.requestLayout()
    }

    /**
     * 还原控件
     * */
    private fun restoreView(view: View) {
        val distance = childView.measuredWidth.toFloat() - currentViewWidth
        val anim = ObjectAnimator
            .ofFloat( distance, 0.0F )
            .setDuration( ( distance * replyRatio ).toLong() )
        anim.interpolator = LinearInterpolator()
        anim.addUpdateListener { animation -> setZoom(animation.animatedValue as Float, view) }
        anim.start()
    }
}